// 用于管理房间内的玩法

var Poker = require('../Poker/Poker');
var constVar = require('./const');
require('./config');
require("../../../util/gameUtil");

exports.Rules = {

    /**
     * 分析当前牌型
     * @param handCards
     * @param rules
     * @returns {*}
     */
    analysis : function (handCards, rules) {

        var handValue = constVar.cardValue.single;

        // 获取花色
        var colorNum = this.getColorNum(handCards);

        // 判断特殊牌型(目前只有不同花色235)
        var spectValue = this.getExSpector(handCards, colorNum, rules);
        if (spectValue) {
            return spectValue;
        }

        // 获取相同牌数
        var sameCard = this.getSameCard(handCards);

        // 获取当前是否是顺子
        var isStraight = this.getIsStaright(handCards);

        // 当前是金花
        if (colorNum == 3 && isStraight) {
            handValue = constVar.cardValue.straightFlush;
        }else if (sameCard == 2) {
            handValue = constVar.cardValue.aPair;
        }else if (sameCard == 3) {
            handValue = constVar.cardValue.baozi;
        }else if (isStraight) {
            handValue = constVar.cardValue.straight;
        }else if (colorNum == 3) {
            handValue = constVar.cardValue.gFlower;
        }else {
            handValue = constVar.cardValue.single;
        }

        return handValue;
    },

    /**
     * 获取手牌中最多牌的花色
     * @param handcards
     * @returns
     */
    getColorList : function (handcards) {

        var colorList = {};

        // 用于获取对应的花色
        for (var index = 0; index < handcards.length ; ++index) {

            var color = Poker.getColor(handcards[index]);

            // 获取当前手牌中花色
            if (colorList[color]) {
                colorList[color] += 1;
            }else {
                colorList[color] = 1;
            }
        }

        return colorList;
    },

    /**
     * 获取花色的数量
     * @param handcards
     * @returns {*}
     */
    getColorNum : function (handcards) {
        var colorList = this.getColorList(handcards);

        var ColorNum = 1;

        for (var color in colorList) {

            if (color != null && colorList[color] > ColorNum) {
                ColorNum = colorList[color];
            }
        }

        return ColorNum;

    },

    /**
     * 用于获取当前最多牌型的数量
     * @param handcards
     * @returns {number}
     */
    getSameCard : function (handcards) {
        var SameCard = 1;

        var sameCardValue = this.getSamePointCard(handcards);

        // 用于获取相同卡牌的数量
        for (var index in sameCardValue) {

            if (index != null && sameCardValue[index] && sameCardValue[index] > SameCard) {
                SameCard = sameCardValue[index];
            }
        }

        return SameCard;
    },

    /**
     * 获取相同牌值的数组
     * @param handcards
     * @returns
     */
    getSamePointCard : function (handcards) {

        var sameCardArray = {};

        for (var index = 0; index < handcards.length; ++index) {
            var point = Poker.getPoint(handcards[index]);

            if (sameCardArray[point]) {
                sameCardArray[point] += 1;
            }else {
                sameCardArray[point] = 1;
            }
        }

        return sameCardArray;
    },

    /**
     * 获取是否是顺子
     * @param handcards
     * @returns {boolean}
     */
    getIsStaright : function (handcards) {

        // 获取对应玩家手牌中的牌
        var list = this.getSortPoker(handcards, true);

        // 特殊情况
        // A23
        if (Poker.getPoint(list[0]) == 2
        && Poker.getPoint(list[1]) == 3
        && Poker.getPoint(list[2]) == 14) {
            return true;
        }

        // 因此直接进行排序就可以了
        for (var index = 1; index < list.length; ++index) {

            if (list[index - 1] != list[index] - 1) {
                return false;
            }
        }

        return true;
    },

    /**
     * 获取特殊牌型
     * @param handcards
     * @param rules
     * @returns {number}
     */
    getExSpector : function(handcards, color, rules) {

        // 判断特殊牌型
        var pokerList = this.getSortPoker(handcards, true);

        // 杂色235
        if (color != 3 && !rules["235_Single"]) {
            if (pokerList[0] == 2 && pokerList[1] == 3 && pokerList[2] == 5) {
                return constVar.cardValue.extValue.dif235;
            }
        }

        return 0;
    },

    /**
     * 获取排列好的扑克
     * @param handcards
     * @param byMax
     * @returns {Array}
     */
    getSortPoker : function (handcards, byMax) {

        var list = [];

        if (byMax == null) {
            byMax = true;
        }

        // 获取对应玩家手牌中的牌
        ExObject.eachKeyNum(handcards, function(k,v) {

            if (v > 0) {

                if (Poker.getPoint(v) == Poker.Point.A) {
                    list.push(14);
                }else {
                    list.push(Poker.getPoint(v));
                }
            }
        });

        // 进行排序
        if (byMax) {
            list.sort(function (a, b) {
                return a - b;
            });
        }else {
            list.sort(function (a, b) {
                return b - a;
            });
        }

        return list;
    },

    /**
     * 比较两个玩家之间的牌型，并获取胜利方
     * @param curPlayer
     * @param anotherPlayer     自己的手牌
     * @param rules             使用的规则
     * @returns {*}
     */
    compareResult : function (curPlayer, anotherPlayer, rules) {

        var compareResult = curPlayer.getIndex();

        compareResult = this.compareByBigOrSmall(curPlayer, anotherPlayer, true, rules);

        //// 首先需要获取对应的比牌规则
        //if (rules['compareRule'] == constVar.compareRule.onlyBigOrSmall) {
        //
        //}else if (rules['compareRule'] == constVar.compareRule.onlyColor) {
        //    compareResult = this.compareByColor(curPlayer, anotherPlayer);
        //}else if (rules['compareRule'] == constVar.compareRule.ALL) {
        //    compareResult = this.compareByAll(curPlayer, anotherPlayer, rules);
        //}

        return compareResult;
    },

    /**
     * 比大小规则
     * @param curPlayer
     * @param anotherPlayer
     * @param isSpec           表示当前是否比较完
     * @param rules
     * @returns {*|number}
     */
    compareByBigOrSmall : function (curPlayer, anotherPlayer, isSpec, rules) {

        var result = this.compareByCardValue(curPlayer, anotherPlayer, rules);

        // 此时双方的牌型相同，需要检测牌中的大小
        if (result == -1) {
            result = this.compareByNum(curPlayer, anotherPlayer);
        }

        // 此时双方的牌型大小相同,需要进行判断是谁进行比牌的
        if (isSpec && result == null) {
            result = anotherPlayer.getIndex();
        }

        return result;
    },

    /**
     * 比花色规则
     * @param curPlayer
     * @param anotherPlayer
     * @returns {*|number}
     */
    compareByColor : function (curPlayer, anotherPlayer) {

        var result = this.compareByCardValue(curPlayer, anotherPlayer);

        // 此时双方的牌型相同,需要进行花色判断
        if (result == -1) {
            result = this.compareByMaxColor(curPlayer, anotherPlayer);
        }

        return result;
    },

    /**
     * 全比
     * @param curPlayer
     * @param anotherPlayer
     * @param rules
     * @returns {*|number}
     */
    compareByAll : function (curPlayer, anotherPlayer, rules) {

        var result = this.compareByCardValue(curPlayer, anotherPlayer, rules);

        if (result == -1) {
            result = this.compareByBigOrSmall(curPlayer, anotherPlayer, false, rules);
        }

        if (result == null) {
            result = this.compareByColor(curPlayer, anotherPlayer);
        }

        return result;
    },

    /**
     * 进行牌型比较
     * @param curPlayer
     * @param anotherPlayer
     * @param rules
     * @returns number
     */
    compareByCardValue : function (curPlayer, anotherPlayer, rules) {

        // 根据牌型进行比较
        // 获取玩家的牌型
        // 如果玩家的牌型不存在，则进行玩家的牌型分析
        // 然后再进行比较
        // 如果当前牌型不存在
        if (curPlayer._cardValue === 0) {
            curPlayer._cardValue = this.analysis(curPlayer.getHandCards().getInitCards(), rules);
        }

        // 比牌问题
        if (anotherPlayer._cardValue === 0) {
            anotherPlayer._cardValue = this.analysis(anotherPlayer.getHandCards().getInitCards(), rules);
        }

        logger.debug ("当前比牌玩家的牌型" + curPlayer._cardValue);
        logger.debug ("被比牌玩家的牌型" + anotherPlayer._cardValue);

        var result = this.compareCardValue (curPlayer._cardValue, anotherPlayer._cardValue);

        if (curPlayer._cardValue == result) {
            return curPlayer.getIndex();
        }else if (anotherPlayer._cardValue == result) {
            return anotherPlayer.getIndex();
        }

        // 比牌型中需要加入对子大小，以及顺子大小（特殊的）， 豹子大小等的比较
        // 普通的顺子和金顺，金花，单牌可以按照大小顺序来进行比较

        // 判断当前的牌是否是对子, 如果是则需要特殊进行判断
        if (result == -1
            && curPlayer._cardValue == constVar.cardValue.aPair
            && anotherPlayer._cardValue == constVar.cardValue.aPair) {
            result = this.compareApair (curPlayer, anotherPlayer);
        }

        // 发送结果
        return result;
    },

    /**
     * 对子大小比较
     * @param curPlayer
     * @param anotherPlayer
     * @returns {*|number}
     */
    compareApair : function (curPlayer, anotherPlayer) {

        var curHandcards = curPlayer.getHandCards().getInitCards();
        var anoHandcards = anotherPlayer.getHandCards().getInitCards();

        var curPoker = Poker.getPoint(curHandcards[0]) == Poker.getPoint(curHandcards[1]) ? curHandcards[0] : curHandcards[2];
        var anoPoker = Poker.getPoint(anoHandcards[0]) == Poker.getPoint(anoHandcards[1]) ? anoHandcards[0] : anoHandcards[2];

        // 需要对A进行特殊处理
        if (Poker.getPoint(curPoker) == Poker.Point.A) {
            var color = Poker.getColor(curPoker);
            curPoker = Poker.getValue(color, 14);
        }

        if (Poker.getPoint(anoPoker) == Poker.Point.A) {
            var color = Poker.getColor(curPoker);
            anoPoker = Poker.getValue(color, 14);
        }

        if (Poker.getPoint(curPoker) > Poker.getPoint(anoPoker)) {
            return curPlayer.getIndex();
        } else if (Poker.getPoint(curPoker) < Poker.getPoint(anoPoker)) {
            return anotherPlayer.getIndex();
        } else {
            return -1;
        }
    },

    /**
     * 比较牌型
     * @param curCardValue
     * @param anoCardValue
     * @returns {number}
     */
    compareCardValue : function (curCardValue, anoCardValue) {

        if (curCardValue == constVar.cardValue.extValue.dif235
            && anoCardValue == constVar.cardValue.baozi) {
            return curCardValue;
        }else if (anoCardValue == constVar.cardValue.extValue.dif235
            && curCardValue == constVar.cardValue.baozi) {
            return anoCardValue;
        }else if (curCardValue == constVar.cardValue.extValue.dif235
            && anoCardValue == constVar.cardValue.extValue.dif235) {
            return -1;
        }else if (curCardValue == constVar.cardValue.extValue.dif235) {
            return anoCardValue;
        }else if (anoCardValue == constVar.cardValue.extValue.dif235) {
            return curCardValue;
        }else {

            // 判断当前的牌型和另外一个玩家的牌型哪一个大
            if (curCardValue == anoCardValue) {
                return -1;
            }

            return curCardValue > anoCardValue ? curCardValue : anoCardValue;
        }

    },

    /**
     * 根据牌的大小进行牌值对比
     * @param curPlayer
     * @param anotherPlayer
     * @returns {number}
     */
    compareByNum : function (curPlayer, anotherPlayer) {

        var result = null;

        // 根据牌中的大小进行对应双方的牌值对比
        // 首先获取两个玩家牌 已经排列 好的、
        var curList = this.getSortPoker(curPlayer.getHandCards().getInitCards(), false);
        var anotherList = this.getSortPoker(anotherPlayer.getHandCards().getInitCards(), false);

        // 然后从头到尾逐次进行比较
        for (var index = 0; index < curList.length; ++index) {

            if (curList[index] > anotherList[index]) {
                result = curPlayer.getIndex();
                break;
            } else if (curList[index] < anotherList[index]) {
                result = anotherPlayer.getIndex();
                break;
            }
        }

        return result;
    },

    /**
     * 根据牌的花色进行比较获取结果
     * @param curPlayer
     * @param anotherPlayer
     * @returns {number}
     */
    compareByMaxColor : function (curPlayer, anotherPlayer) {

        // 各获取两个玩家牌当中最大的一张牌
        var curMaxCard = this.getMaxCard(curPlayer.getHandCards().getInitCards());
        var anotherPlayerCard = this.getMaxCard(anotherPlayer.getHandCards().getInitCards());

        // 首先比较最大牌值
        if (Poker.getPoint(curMaxCard) > Poker.getPoint(anotherPlayerCard)) {
            return curPlayer.getIndex();
        }else if (Poker.getPoint(curMaxCard) < Poker.getPoint(anotherPlayerCard)) {
            return anotherPlayer.getIndex();
        }

        var curMaxCardColor = Poker.getColor(curMaxCard);
        var anotherPlayerColor = Poker.getColor(anotherPlayerCard);

        // 然后根据最大牌的花色进行比较
        if (constVar.compareColorValue[curMaxCardColor] < constVar.compareColorValue[anotherPlayerColor]) {
            return curPlayer.getIndex();
        }else {
            return anotherPlayer.getIndex();
        }
    },

    /**
     * 获取最大牌
     * @param handcards
     * @returns {number}
     */
    getMaxCard : function (handcards) {

        var maxCardValue = 0;
        var maxPokerValue;

        // 特殊判断
        if (cardValue == constVar.cardValue.aPair) {
            return this.getPairColorValue();
        }

        // 获取对应玩家手牌中的牌
        for (var index = 0; index < handcards.length; ++index) {

            var point = handcards[index];

            // 由于拿出来之后是直接比较..设定的A值为1，比较会有问题，因此，当前改为14
            if (Poker.getPoint(point) == Poker.Point.A) {
                maxCardValue = 14;
                var color = Poker.getColor(point);
                maxPokerValue = Poker.getValue(color, maxCardValue);
            }

            if (Poker.getPoint(point) > maxCardValue) {
                maxCardValue = Poker.getPoint(point);
                maxPokerValue = point;
            }

        }

        return maxPokerValue;
    },

    /**
     * 用于获取比花色中对子比较大牌值的那一个值
     * @param handcards
     */
    getPairColorValue : function (handcards) {

        // 首先获取最大的对子牌值
        var point = Poker.getPoint(handcards[0]) == Poker.getPoint(handcards[1]) ? handcards[0] : handcards[2];
        var tempColor = Poker.getColor(point);
        var colorValue = point;

        for (var index = 0; index < handcards.length; ++index) {

            if (Poker.getPoint(handcards[index]) == Poker.getPoint(point)) {

                var color = Poker.getColor(handcards[index]);
                if (constVar.compareColorValue[color] < constVar.compareColorValue[tempColor]) {
                    tempColor = color;
                    colorValue = handcards[index];
                }
            }
        }

        // 将A值进行转换
        if (Poker.getPoint(colorValue) == Poker.Point.A) {
            colorValue = Poker.getValue(tempColor, 14);
        }

        return colorValue;
    },

    /**
     * 当前玩家扑克进行大小排序
     * @param handCards
     * @param byNumMax  是按照升序还是降序进行排列
     */
    sortPlayerPokerByNum : function (handCards, byNumMax) {

        var list = [];
        var hasA = false;
        var APoker = [];

        for (var index = 0; index < handCards.length; ++index) {

            // A需要特殊处理
            if (Poker.getPoint(handCards[index]) == Poker.Point.A) {
                hasA = true;
                APoker.push(handCards[index]);
            }else{
                list.push (handCards[index]);
            }
        }

        if (byNumMax) {
            list.sort(function (a, b) {
                return Poker.getPoint(a) - Poker.getPoint(b);
            });

            if (hasA) {

                for (var index = 0; index < APoker.length; ++index) {
                    list.push(APoker[index]);
                }
            }
        }else {

            for (var index = 0; index < APoker.length; ++index) {
                list.push(APoker[index]);
            }

            list.sort(function (a, b) {
                return Poker.getPoint(b) - Poker.getPoint(a);
            });
        }

        return list;
    }
};
